package com.onluy.framework.system.common;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.onluy.framework.data.util.InParam;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; 

public class Common
{
  protected Logger log = LoggerFactory.getLogger(getClass());
  private static Common common;

  public static Common getInstance()
  {
    if (common == null) {
      common = new Common();
    }
    return common;
  }

  public String getTimestampFormat(String value)
  {
    switch (value.length()) {
    case 4:
      return "yyyy";
    case 6:
      return "yyyyMM";
    case 7:
      return "yyyy-MM";
    case 8:
      return "yyyyMMdd";
    case 10:
      return "yyyy-MM-dd";
    case 13:
      return "yyyy-MM-dd HH";
    case 16:
      return "yyyy-MM-dd HH:mm";
    case 19:
      return "yyyy-MM-dd HH:mm:ss";
    case 21:
      return "yyyy-MM-dd HH:mm:ss.S";
    case 5:
    case 9:
    case 11:
    case 12:
    case 14:
    case 15:
    case 17:
    case 18:
    case 20: } return null;
  }

  public String getMatchStr(String str, String regex)
  {
    List result = getMatchArray(str, regex);
    return result.size() == 0 ? null : (String)result.get(0);
  }

  public List getMatchArray(String str, String regex)
  {
    List result = new ArrayList();

    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(str);
    while (matcher.find()) {
      result.add(matcher.group());
    }

    return result;
  }

  public boolean isMatches(String str, String regex)
  {
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(str);
    return matcher.matches();
  }

  public String trimPrefix(String str, String prefix)
  {
    return str.startsWith(prefix) ? str.substring(prefix.length()) : str;
  }

  public String trimSuffix(String str, String suffix)
  {
    return str.endsWith(suffix) ? str.substring(0, str.length() - 1) : str;
  }

  public String getStrByArray(String[] array)
  {
    return getStrByArray(array, ",");
  }

  public String getStrByArray(String[] array, String split)
  {
    StringBuilder str = new StringBuilder();
    for (int i = 0; i < array.length; i++) {
      str.append(new StringBuilder().append(array[i]).append(i != array.length - 1 ? split : "").toString());
    }
    return str.toString();
  }

  public String encodeCharset(String charSet)
  {
    String set = null;
    try {
      set = new String(charSet.getBytes("GBK"), "ISO8859_1");
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
    return set;
  }

  public String decodeCharset(String charSet)
  {
    String set = null;
    try {
      set = new String(charSet.getBytes("ISO8859_1"), "GBK");
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(e);
    }
    return set;
  }

  public Date encodeTimestamp(String timeStr)
  {
    if ((timeStr == null) || ("".equals(timeStr))) {
      return null;
    }
    String format = getTimestampFormat(timeStr);
    return encodeTimestamp(format, timeStr);
  }

  public Date encodeTimestamp(String format, String timeStr)
  {
    if ((timeStr == null) || ("".equals(timeStr))) {
      return null;
    }
    Date date = null;
    if ((null == timeStr) || ("".equals(timeStr)))
      return null;
    if (format.length() != timeStr.length())
      format = getTimestampFormat(timeStr);
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    try {
      date = new Timestamp(sdf.parse(timeStr).getTime());
    } catch (ParseException e) {
      throw new RuntimeException(e);
    }
    return date;
  }

  public String decodeTimeStr(String format, String timeStr)
  {
    Date time = encodeTimestamp(format, timeStr);
    return decodeTimestamp(format, time);
  }

  public String decodeTimestamp(String format, Date time)
  {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    return sdf.format(time);
  }

  public Date getCurrentTime()
  {
    return new Timestamp(System.currentTimeMillis());
  }

  public String getSysTime()
  {
    return decodeTimestamp("yyyy-MM-dd HH:mm:ss", new Timestamp(System.currentTimeMillis()));
  }

  public String getSysDate()
  {
    return decodeTimestamp("yyyy-MM-dd", new Timestamp(System.currentTimeMillis()));
  }

  public String getLastDay()
  {
    return getLastDay(getSysDate());
  }

  public String getLastDay(String timestr)
  {
    Calendar cal = Calendar.getInstance();
    cal.setTime(encodeTimestamp(timestr));
    cal.set(5, cal.getActualMaximum(5));

    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
    return dateformat.format(cal.getTime());
  }

  public String getPrevDayByCurrDate()
  {
    Calendar cal = Calendar.getInstance();
    cal.add(5, -1);

    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
    return dateformat.format(cal.getTime());
  }

  public String getPrevMonthFirstDay()
  {
    Calendar cal = Calendar.getInstance();
    cal.add(2, -1);
    cal.set(5, 1);

    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
    return dateformat.format(cal.getTime());
  }

  public String formatDecimal(String format, double decimal)
  {
    DecimalFormat df = new DecimalFormat(format);
    return df.format(decimal);
  }

  public URL getClassResource(String file)
  {
    URL url = getClass().getClassLoader().getResource(file);
    if (url == null)
      error(new StringBuilder().append("file ").append(file).append(" not exist!").toString());
    return url;
  }

  public int getCharLength(String value)
  {
    char[] chars = value.toCharArray();

    int charlen = 0;
    for (int i = 0; i < chars.length; i++) {
      if (chars[i] > '')
        charlen += 2;
      else {
        charlen++;
      }
    }

    return charlen;
  }

  public int getCharLength(String value, int length)
  {
    char[] chars = value.toCharArray();
    if (chars.length < length) {
      length = chars.length;
    }
    int charidx = 0; int charlen = 0;
    while (charlen < length) {
      if (chars[charidx] > '')
        charlen += 2;
      else {
        charlen++;
      }
      charidx++;
    }

    return charidx;
  }

  public List getArrayByCodingStr(String namestr, String encodestr)
  {
    String[] encodename = namestr.split(",");

    int tablen = 4; int rowlen = 4; int collen = 3;
    int rows = Integer.parseInt(encodestr.substring(tablen, tablen + rowlen));
    String content = encodestr.substring(tablen + rowlen + collen);

    List dataset = new ArrayList();
    for (int i = 0; i < rows; i++) {
      Map data = new HashMap();
      for (int j = 0; j < encodename.length; j++)
      {
        int namelen = Integer.parseInt(content.substring(0, 4));
        content = content.substring(4);
        int vallen = getCharLength(content, namelen);
        String value = content.substring(0, vallen);
        content = content.substring(vallen);

        data.put(encodename[j], value);
      }
      dataset.add(data);
    }

    return dataset;
  }

  public Map putDataByEntity(Object entity)
    throws Exception
  {
    Map data = new HashMap();
    Method[] methods = entity.getClass().getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
      String methodName = methods[i].getName();
      if (methodName.startsWith("get")) {
        String paramName = methodName.substring(3, methodName.length());
        data.put(paramName, methods[i].invoke(entity, null));
      }
    }
    return data;
  }

  public Object putEntityByData(Object entity, Map data)
    throws Exception
  {
    Method[] methods = entity.getClass().getDeclaredMethods();
    for (int i = 0; i < methods.length; i++) {
      Method method = methods[i];
      String methodName = method.getName();
      if (methodName.startsWith("set")) {
        Class methodType = method.getParameterTypes()[0];
        Object[] params = new Object[1];

        String paramName = methodName.substring(3, methodName.length()).toUpperCase();
        Object paramValue = data.get(paramName);
        if (paramValue == null) {
          continue;
        }
        params[0] = paramValue;

        if (String.class.isAssignableFrom(methodType))
          params[0] = paramValue;
        else if (Date.class.isAssignableFrom(methodType))
          params[0] = encodeTimestamp((String)paramValue);
        else if (Long.class.isAssignableFrom(methodType))
          params[0] = new Long(paramValue.toString());
        else if (Integer.class.isAssignableFrom(methodType))
          params[0] = new Integer(paramValue.toString());
        else if (Short.class.isAssignableFrom(methodType))
          params[0] = new Short(paramValue.toString());
        else if (Double.class.isAssignableFrom(methodType))
          params[0] = new Double(paramValue.toString());
        else if (Float.class.isAssignableFrom(methodType))
          params[0] = new Float(paramValue.toString());
        else if (Boolean.class.isAssignableFrom(methodType)) {
          params[0] = new Boolean(paramValue.toString());
        }

        method.invoke(entity, params);
      }
    }
    return entity;
  }

  public Object callBean(String class_name, String method_name)
    throws Exception
  {
    return callBean(class_name, method_name, null, null);
  }

  public Object callBean(String class_name, String method_name, Object[] params)
    throws Exception
  {
    return callBean(class_name, method_name, params, null);
  }

  public Object callBean(String class_name, String method_name, Object[] params, Class[] types)
    throws Exception
  {
    Class cls = Class.forName(class_name);
    Object instance = cls.newInstance();
    if (types == null) {
      types = new Class[params.length];
    }
    if ((params != null) && (types != null)) {
      for (int i = 0; i < types.length; i++) {
        if (types[i] == null)
          types[i] = params[i].getClass();
      }
    }
    Method method = cls.getMethod(method_name, types);
    return method.invoke(instance, params);
  }

  public Object callBean(Object instance, String method_name, Object[] params, Class[] types)
    throws Exception
  {
    if ((params != null) && (types != null)) {
      for (int i = 0; i < types.length; i++) {
        if (types[i] == null) {
          types[i] = params[i].getClass();
        }
      }
    }
    Method method = instance.getClass().getMethod(method_name, types);
    return method.invoke(instance, params);
  }

 /* public String getProperty(String prop)
  {
    return getProperty(prop, null);
  }
*/
 /* public String getProperty(String prop, String defval)
  {
    return getProperty("application.xml", prop, defval);
  }
*/
 /* public String getProperty(String file, String prop, String defval)
  {
    ICache cache = getCacheManager().getICache("COM_CONFIG_COLLECT");
    if ((cache != null) && (cache.get(prop) != null)) {
      return (String)cache.get(prop);
    }

    String result = null;
    try {
      IConfig config = new XMLConfig(file);
      result = config.getProperty(prop);
    } catch (Exception e) {
      if (defval == null)
        error(new StringBuilder().append("application config ").append(prop).append(" reading error!").toString(), e);
      else
        result = defval;
    }
    finally {
      if ((result == null) && (defval != null)) {
        result = defval;
      }
      if ((result != null) && 
        (cache != null)) {
        cache.put(prop, result);
      }

    }

    return result;
  }

  public IData getProperties(String prop)
  {
    return getProperties("application.xml", prop);
  }

  public IData getProperties(String file, String prop)
  {
    ICache cache = getCacheManager().getICache("COM_CONFIG_COLLECT");
    if ((cache != null) && (cache.get(prop) != null)) {
      return (IData)cache.get(prop);
    }
    try
    {
      IConfig config = new XMLConfig(file);
      IData result = config.getProperties(prop);

      if (cache != null) {
        cache.put(prop, result);
      }

      return result;
    } catch (Exception e) {
      error(new StringBuilder().append("application config ").append(prop).append(" reading error!").toString(), e);
    }

    return null;
  }*/

  public void error(String message)
    throws RuntimeException
  {
    RuntimeException exception = new RuntimeException(message);
    this.log.error(message);
    throw exception;
  }

  public void error(Exception e)
    throws RuntimeException
  {
    RuntimeException exception = new RuntimeException(e);
    this.log.error(e.getMessage(), exception);
    throw exception;
  }

  public void error(String message, Exception e)
    throws RuntimeException
  {
    RuntimeException exception = new RuntimeException(message, e);
    this.log.error(message, exception);
    throw exception;
  }

  public String[] getValues(Object value)
  {
    if (value == null)
      return new String[0];
    if ((value instanceof String[])) {
      return (String[])(String[])value;
    }
    return new String[] { (String)value };
  }
  /*
  public String getHintInfo(String prop)
    throws Exception
  {
    ICache cache = getCacheManager().getICache("SYS_COLUMNS_CACHE");
    if ((cache != null) && (cache.get(prop) != null)) {
      return (String)cache.get(prop);
    }

    IConfig config = new TEXTConfig(prop.startsWith("component.") ? "hint_wadelib.txt" : "hint.txt");
    String result = config.getProperty(prop);
    if (result != null) {
      String tmp = URLDecoder.decode(result, "GBK");
      result = tmp;
    }
    if (cache != null) {
      cache.put(prop, result);
    }
    return result;
  }

  public ICacheManager getCacheManager()
  {
    String springCacheManager = SpringPropertyHolder.getContextProperty("cacheManagerName", "springCacheManager");
    return (ICacheManager)SpringContextHolder.getBean(springCacheManager, ICacheManager.class);
  }*/

  public String toChineseMoney(String money)
  {
    if (money == null)
      return null;
    String prefix = money.startsWith("-") ? "负" : "";
    money = money.replaceAll("-", "");
    String[] part = money.split("\\.");
    String newchar = "";
    for (int i = part[0].length() - 1; i >= 0; i--) {
      if (part[0].length() > 10) {
        error("位数过大，无法计算");
      }
      String tmpnewchar = "";
      char perchar = part[0].charAt(i);
      switch (perchar) {
      case '0':
        tmpnewchar = new StringBuilder().append("零").append(tmpnewchar).toString();
        break;
      case '1':
        tmpnewchar = new StringBuilder().append("壹").append(tmpnewchar).toString();
        break;
      case '2':
        tmpnewchar = new StringBuilder().append("贰").append(tmpnewchar).toString();
        break;
      case '3':
        tmpnewchar = new StringBuilder().append("叁").append(tmpnewchar).toString();
        break;
      case '4':
        tmpnewchar = new StringBuilder().append("肆").append(tmpnewchar).toString();
        break;
      case '5':
        tmpnewchar = new StringBuilder().append("伍").append(tmpnewchar).toString();
        break;
      case '6':
        tmpnewchar = new StringBuilder().append("陆").append(tmpnewchar).toString();
        break;
      case '7':
        tmpnewchar = new StringBuilder().append("柒").append(tmpnewchar).toString();
        break;
      case '8':
        tmpnewchar = new StringBuilder().append("捌").append(tmpnewchar).toString();
        break;
      case '9':
        tmpnewchar = new StringBuilder().append("玖").append(tmpnewchar).toString();
      }

      switch (part[0].length() - i - 1) {
      case 0:
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("元").toString();
        break;
      case 1:
        if (perchar == 0) break;
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("拾").toString(); break;
      case 2:
        if (perchar == 0) break;
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("佰").toString(); break;
      case 3:
        if (perchar == 0) break;
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("仟").toString(); break;
      case 4:
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("万").toString();
        break;
      case 5:
        if (perchar == 0) break;
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("拾").toString(); break;
      case 6:
        if (perchar == 0) break;
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("佰").toString(); break;
      case 7:
        if (perchar == 0) break;
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("仟").toString(); break;
      case 8:
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("亿").toString();
        break;
      case 9:
        tmpnewchar = new StringBuilder().append(tmpnewchar).append("拾").toString();
      }

      newchar = new StringBuilder().append(tmpnewchar).append(newchar).toString();
    }
    if (money.indexOf(".") != -1) {
      if (part[1].length() > 2) {
        this.log.warn("小数点之后只能保留两位,系统将自动截断");
        part[1] = part[1].substring(0, 2);
      }
      for (int i = 0; i < part[1].length(); i++) {
        String tmpnewchar = "";
        char perchar = part[1].charAt(i);
        switch (perchar) {
        case '0':
          tmpnewchar = new StringBuilder().append("零").append(tmpnewchar).toString();
          break;
        case '1':
          tmpnewchar = new StringBuilder().append("壹").append(tmpnewchar).toString();
          break;
        case '2':
          tmpnewchar = new StringBuilder().append("贰").append(tmpnewchar).toString();
          break;
        case '3':
          tmpnewchar = new StringBuilder().append("叁").append(tmpnewchar).toString();
          break;
        case '4':
          tmpnewchar = new StringBuilder().append("肆").append(tmpnewchar).toString();
          break;
        case '5':
          tmpnewchar = new StringBuilder().append("伍").append(tmpnewchar).toString();
          break;
        case '6':
          tmpnewchar = new StringBuilder().append("陆").append(tmpnewchar).toString();
          break;
        case '7':
          tmpnewchar = new StringBuilder().append("柒").append(tmpnewchar).toString();
          break;
        case '8':
          tmpnewchar = new StringBuilder().append("捌").append(tmpnewchar).toString();
          break;
        case '9':
          tmpnewchar = new StringBuilder().append("玖").append(tmpnewchar).toString();
        }

        if (i == 0)
          tmpnewchar = new StringBuilder().append(tmpnewchar).append("角").toString();
        if (i == 1) {
          tmpnewchar = new StringBuilder().append(part[1].charAt(0) == '0' ? "零" : "").append(tmpnewchar).append("分").toString();
        }
        newchar = new StringBuilder().append(newchar).append(tmpnewchar).toString();
      }
    }

    while (newchar.indexOf("零零") != -1)
      newchar = newchar.replaceAll("零零", "零");
    newchar = newchar.replaceAll("零亿", "亿");
    newchar = newchar.replaceAll("亿万", "亿");
    newchar = newchar.replaceAll("零万", "万");
    if (!newchar.startsWith("零元"))
      newchar = newchar.replaceAll("零元", "元");
    newchar = newchar.replaceAll("零角", "");
    newchar = newchar.replaceAll("零分", "");
    if ((newchar.charAt(newchar.length() - 1) == '元') || (newchar.charAt(newchar.length() - 1) == 35282))
      newchar = new StringBuilder().append(newchar).append("整").toString();
    return new StringBuilder().append(prefix).append(newchar).toString();
  }

  public Object reflectInvoke(Object bean, String funcName, Object[] params, Class[] types)
    throws Exception
  {
    Object ret = null;
    Class[] Params = new Class[params.length];
    for (int i = 0; i < params.length; i++) {
      if ((types != null) && (types[i] != null))
        Params[i] = types[i];
      else if (params[i] != null)
        Params[i] = params[i].getClass();
    }
    Method method = bean.getClass().getMethod(funcName, Params);

    ret = method.invoke(bean, params);

    return ret;
  }

  public String getPartitionId(String id)
  {
    return getPartitionId(id, 4);
  }

  public String getPartitionId(String id, int length)
  {
    return String.valueOf(Long.parseLong(id) % (int)Math.pow(10.0D, length));
  }

  public boolean equalsNVL(Object obj1, Object obj2)
  {
    if ((obj1 == null) && (obj2 == null)) {
      return true;
    }

    return (obj1 != null) && (obj2 != null) && (obj1.equals(obj2));
  }

  public int hashCodeNVL(Object o)
  {
    if (o == null) {
      return 0;
    }
    return o.hashCode();
  }

  public String getStackTrace(Object e) {
    return getStackTrace((Throwable)e, 0);
  }

  public String getStackTrace(Throwable e, int maxLength) {
    StringWriter sw = new StringWriter();
    PrintWriter pw = new PrintWriter(sw);
    e.printStackTrace(pw);
    String str = sw.toString();
    if (maxLength == 0) {
      return str;
    }
    int charLength = getCharLength(str, maxLength);
    return str.substring(0, charLength);
  }

  public String getErrorMessage(Object e)
  {
    String msg = "";
    if ((e instanceof Throwable)) {
      msg = ((Throwable)e).getMessage();
      if ((null == e) || (((e instanceof RuntimeException)) && (!e.getClass().equals(RuntimeException.class))) || (StringUtils.isBlank(msg))) {
        return "出错了！:(";
      }
    }
    int messageSplit = -1;
    if ((messageSplit = msg.lastIndexOf("Exception:")) == -1) {
      return msg;
    }
    return msg.substring(messageSplit + 10);
  }

  public Field getFieldByFieldName(Object obj, String fieldName)
  {
    for (Class superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
      try {
        return superClass.getDeclaredField(fieldName);
      }
      catch (NoSuchFieldException e) {
      }
    return null;
  }

  public Object getValueByFieldName(Object obj, String fieldName)
    throws Exception
  {
    String methodName = new StringBuilder().append("get").append(toUpperCaseFirstOne(fieldName)).toString();
    try {
      obj.getClass().getMethod(methodName, null);
    } catch (Exception e) {
      return null;
    }
    return callBean(obj, methodName, null, null);
  }

  public void setValueByFieldName(Object obj, String fieldName, Object value)
    throws Exception
  {
    String methodName = new StringBuilder().append("set").append(toUpperCaseFirstOne(fieldName)).toString();
    Field field = null;
    try {
      field = obj.getClass().getDeclaredField(fieldName);
      obj.getClass().getMethod(methodName, new Class[] { field.getType() });
    } catch (Exception e) {
      return;
    }

    callBean(obj, methodName, new Object[] { value }, new Class[] { field.getType() });
  }

  public String toLowerCaseFirstOne(String s)
  {
    if (Character.isLowerCase(s.charAt(0))) {
      return s;
    }
    return new StringBuilder().append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString();
  }

  public String toUpperCaseFirstOne(String s)
  {
    if (Character.isUpperCase(s.charAt(0))) {
      return s;
    }
    return new StringBuilder().append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
  }

  public String getUniqeName() {
    return new StringBuilder().append(String.valueOf(System.currentTimeMillis())).append(Math.abs(new Random().nextInt())).toString();
  }

  public boolean isBasicType(Class<?> clazz)
  {
    return (String.class.isAssignableFrom(clazz)) || (Number.class.isAssignableFrom(clazz)) || (Boolean.class.isAssignableFrom(clazz)) || (Character.class.isAssignableFrom(clazz));
  }

  public String replaceBlank(String str)
  {
    Pattern p = Pattern.compile("\\s*|\t|\r|\n");
    Matcher m = p.matcher(str);
    return m.replaceAll("");
  }

  public String transParamDecode(String param, String charset)
  {
    if (param == null)
      return null;
    try
    {
      return URLDecoder.decode(param, charset).trim();
    } catch (UnsupportedEncodingException e) {
    }
    return null;
  }

  public HttpServletRequest getContextRequest()
  {
    ServletRequestAttributes ra = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = ra.getRequest();
    return request;
  }

  public List[] getSubLists(List list, int sub)
  {
    List[] lists = null;
    if (list.size() > 0) {
      int subNums = list.size() / sub > 0 ? list.size() / sub + (list.size() % sub == 0 ? 0 : 1) : 1;
      lists = new List[subNums];
      for (int i = 0; i < subNums; i++) {
        List subList = null;
        if (i != subNums - 1)
          subList = list.subList(i * sub, (i + 1) * sub);
        else {
          subList = list.subList(i * sub, list.size());
        }
        lists[i] = subList;
      }
    }
    return lists;
  }

  public boolean isAjaxRequest(HttpServletRequest request)
  {
    String header = request.getHeader("X-Requested-With");
    boolean isAjax = "XMLHttpRequest".equals(header);
    return isAjax;
  }

  public String getErrorInfo(String errorInfo)
  {
    if (StringUtils.isBlank(errorInfo)) {
      return "";
    }
    if (errorInfo.startsWith("java.lang.RuntimeException:")) {
      errorInfo = errorInfo.substring("java.lang.RuntimeException:".length());
    }
    return errorInfo.replaceAll("\\n", "<br/>").replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
  }

  public String getRandomString(int length)
  {
    String base = "abcdefghijklmnopqrstuvwxyz";
    Random random = new Random();
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
      int number = random.nextInt(base.length());
      sb.append(base.charAt(number));
    }
    return sb.toString();
  }

  public String getIpAddr(HttpServletRequest request)
  {
    String ip = request.getHeader("x-forwarded-for");
    if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
      ip = request.getHeader("Proxy-Client-IP");
    }
    if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
      ip = request.getHeader("WL-Proxy-Client-IP");
    }
    if ((ip == null) || (ip.length() == 0) || ("unknown".equalsIgnoreCase(ip))) {
      ip = request.getRemoteAddr();
    }
    return ip;
  }

  public InParam<String, Object> getInParam(HttpServletRequest request)
  {
    InParam inParam = new InParam();
    Enumeration fields = request.getParameterNames();
    while (fields.hasMoreElements()) {
      String field = (String)fields.nextElement();
      String[] values = request.getParameterValues(field);
      if (values.length > 1)
        inParam.put(field, values);
      else {
        inParam.put(field, values[0]);
      }
    }

    putFilterRules(inParam);
    return inParam;
  }

  public InParam<String, Object> getGroupInParam(InParam<String, Object> inParam, String group)
  {
    return getGroupInParam(inParam, group, false);
  }

  public InParam<String, Object> getGroupInParam(InParam<String, Object> inParam, String group, boolean istrim)
  {
    InParam element = new InParam();
    String[] names = inParam.getNames();
    for (int i = 0; i < names.length; i++) {
      if (names[i].startsWith(new StringBuilder().append(group).append("_").toString())) {
        element.put(istrim ? names[i].substring(new StringBuilder().append(group).append("_").toString().length()) : names[i], inParam.get(names[i]));
      }
    }
    return element;
  }

  public void putFilterRules(InParam<String, Object> inParam)
  {
    String filterRules = inParam.getString("filterRules");
    if (!StringUtils.isEmpty(filterRules)) {
      JSONArray arr = JSONArray.parseArray(filterRules);
      if (arr.size() > 0) {
        String filterField = String.valueOf(arr.getJSONObject(0).get("field"));
        String filterFieldValue = String.valueOf(arr.getJSONObject(0).get("value"));
        inParam.put(filterField, filterFieldValue);
      }
    }
  }
}